package menu

import (
	"context"
	"go-zero-project/common/excption"
	"go-zero-project/services/user/rpc/constans"
	"go-zero-project/services/user/rpc/internal/mapper"
	"go-zero-project/services/user/rpc/internal/mapper/bo"

	"go-zero-project/services/user/rpc/internal/svc"
	"go-zero-project/services/user/rpc/pb"

	"github.com/zeromicro/go-zero/core/logx"
)

type MenuInfoLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewMenuInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MenuInfoLogic {
	return &MenuInfoLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *MenuInfoLogic) MenuInfo(in *pb.MenuInfoReq) (*pb.MenuInfoResp, error) {
	// 1.查询菜单信息
	menuBO := bo.SysMenuBO{MenuId: in.MenuId}
	rootMenuInfo, err := mapper.NewMenuMapper().SelectOne(l.svcCtx.DBEngin, menuBO)
	if err != nil {
		return nil, err
	}
	if rootMenuInfo.MenuId <= 0 && len(rootMenuInfo.Name) <= 0 {
		return nil, excption.NewErrCode(constans.MenuNoExistError)
	}
	info := &pb.MenuInfoResp{
		MenuId:   rootMenuInfo.MenuId,
		ParentId: rootMenuInfo.ParentId.Int64,
		Name:     rootMenuInfo.Name,
		Url:      rootMenuInfo.Url,
		Perms:    rootMenuInfo.Perms,
		MenuType: int32(rootMenuInfo.Type.Int16),
		Icon:     rootMenuInfo.Icon,
		OrderNum: rootMenuInfo.OrderNum.Int32,
	}
	// 2.递归子菜单
	treeList, err := l.getMenuTreeList(info)
	if nil != err {
		return nil, err
	}
	info.List = treeList
	return info, nil
}

func (l *MenuInfoLogic) queryListParentId(menuId int64) ([]pb.MenuInfoResp, error) {
	menuEntityArr, err := mapper.NewMenuMapper().QueryListParentId(l.svcCtx.DBEngin, menuId)
	if err != nil {
		logx.Errorf("mapper.NewMenuMapper().QueryListParentId failed:%s", err.Error())
		return nil, err
	}
	var navArr []pb.MenuInfoResp
	if len(menuEntityArr) == 0 {
		return navArr, err
	}
	for _, v := range menuEntityArr {
		navArr = append(navArr, pb.MenuInfoResp{
			MenuId:   v.MenuId,
			ParentId: v.ParentId.Int64,
			Name:     v.Name,
			Url:      v.Url,
			Perms:    v.Perms,
			MenuType: int32(v.Type.Int16),
			Icon:     v.Icon,
			OrderNum: v.OrderNum.Int32,
		})
	}
	return navArr, err
}

func (l *MenuInfoLogic) getMenuTreeList(info *pb.MenuInfoResp) ([]*pb.MenuInfoResp, error) {
	var subArr []*pb.MenuInfoResp
	arr, err := l.queryListParentId(info.MenuId)
	if err != nil {
		return nil, err
	}
	for i := 0; i < len(arr); i++ {
		v := pb.MenuInfoResp{
			MenuId:   arr[i].MenuId,
			ParentId: arr[i].ParentId,
			Name:     arr[i].Name,
			Url:      arr[i].Url,
			Perms:    arr[i].Perms,
			MenuType: arr[i].MenuType,
			Icon:     arr[i].Icon,
			OrderNum: arr[i].OrderNum,
			List:     arr[i].List,
		}
		menuTreeList, menuTreeErr := l.getMenuTreeList(&v)
		if menuTreeErr != nil {
			return nil, menuTreeErr
		}
		v.List = menuTreeList
		subArr = append(subArr, &v)
	}

	return subArr, nil

}
